﻿using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Reflection;

namespace Suucha.Expressions
{
    /// <summary>
    /// 和System.Type操作有关的扩展类
    /// </summary>
    public static class TypeExtentions
    {
        /// <summary>
        /// 根据属性名称获取属性信息，如果type指定的类型没有改属性名称，则从type实现了的接口中去查找
        /// </summary>
        /// <param name="type">类型</param>
        /// <param name="name">属性名称</param>
        /// <returns>返回属性信息，如果没有找到，返回null。</returns>
        public static PropertyInfo GetPropertyEx(this Type type, string name)
        {
            PropertyInfo pi = type.GetProperty(name);
            if (pi == null)
            {
                if (type.IsInterface)
                {
                    pi = type.GetPropertyFromInterface(name);
                }
            }
            return pi;
        }
        /// <summary>
        /// 根据属性名称从指定的接口类型中获取
        /// </summary>
        /// <param name="interfaceType">接口类型</param>
        /// <param name="propertyName">属性名称</param>
        /// <returns>返回属性信息，如果没有找到返回null</returns>
        public static PropertyInfo GetPropertyFromInterface(this Type interfaceType, string propertyName)
        {
            PropertyInfo pi = interfaceType.GetProperty(propertyName);
            if (pi != null)
            {
                return pi;
            }
            foreach (Type parent in interfaceType.GetInterfaces())
            {
                pi = GetPropertyFromInterface(parent, propertyName);
                if (pi != null)
                {
                    break;
                }
            }
            return pi;
        }
        /// <summary>
        /// 判断是否是Nullable类型
        /// </summary>
        /// <param name="type">需要判断的类型</param>
        /// <returns>如果是返回true，否则返回false。</returns>
        public static bool IsNullableType(this Type type)
        {
            return type.IsGenericType && type.GetGenericTypeDefinition() == typeof(Nullable<>);
        }
        /// <summary>
        /// 获取非Nullable类型
        /// </summary>
        /// <param name="type">类型</param>
        /// <returns></returns>
        public static Type GetNonNullableType(this Type type)
        {
            return IsNullableType(type) ? type.GetGenericArguments()[0] : type;
        }

    }
}
